package com.changanw.middleware.rpc.config;

import com.changanw.middleware.rpc.domain.LocalServerInfo;
import com.changanw.middleware.rpc.network.server.ServerSocket;
import com.changanw.middleware.rpc.registry.RedisRegistryCenter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;

/**
 *  ServerAutoConfiguration 加载 yml 配置，以及 spring 的处理方式，加载 xml 配置。
 *  无论是使用 RPC 的那一端，都需要启动注册中心以及一个服务端。
 *  注册中心是为了接口的注册和拉取，这里使用的是 Redis 模拟的注册中心
 *  RedisRegistryCenter.init(serverProperties.getHost(), serverProperties.getPort());
 * 服务端是为了所有 RPC 接口的链接，其实每一个应用既可以是接口的提供者，
 * 也可以是其他接口的消费者。那么就需要自己启动一个等待被链接的服务端 new ServerSocket(applicationContext)
 */
public class ServerAutoConfiguration implements ApplicationContextAware {

    private Logger logger = LoggerFactory.getLogger(ServerAutoConfiguration.class);

    @Resource
    private ServerProperties serverProperties;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        logger.info("启动Redis模拟注册中心开始");
        if (StringUtils.hasText(serverProperties.getPassword())) {
            RedisRegistryCenter.init(serverProperties.getHost(), serverProperties.getPort(), serverProperties.getPassword());
        } else {
            RedisRegistryCenter.init(serverProperties.getHost(), serverProperties.getPort());
        }
        logger.info("启动Redis模拟注册中心完成，{} {}", serverProperties.getHost(), serverProperties.getPort());

        logger.info("初始化生产端服务开始");
        ServerSocket serverSocket = new ServerSocket(applicationContext);
        Thread thread = new Thread(serverSocket);
        thread.start();
        while (!serverSocket.isActiveSocketServer()) {
            try {
                Thread.sleep(500);
            } catch (InterruptedException ignore) {
            }
        }
        logger.info("初始化生产端服务完成 {} {}", LocalServerInfo.LOCAL_HOST, LocalServerInfo.LOCAL_PORT);
    }

}
